/*
 * File:         ParseRequest.java
 * Author:       Robert Bittle <guywithnose@gmail.com>
 */
package servlets;

import java.io.IOException;
import java.util.GregorianCalendar;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import data.JavaCurl;
import faceBook.User;
import foxtrotbravo.Config;

/**
 * The Class signedRequest.
 */
public class ParseRequest extends AuthenticationServlet
{

  private static final Logger log = Logger.getLogger(ParseRequest.class
      .getName());
  
  /*
   * (non-Javadoc)
   * 
   * @see
   * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
   * javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected void doGet(HttpServletRequest req,
      HttpServletResponse resp)
      throws ServletException, IOException
  {
    if(createUser(req.getParameter("accessToken"),
        Long.valueOf(req.getParameter("userId"))))
    {
      resp.getWriter().write(successJson());
    } else
    {
      resp.getWriter().write(errorJson("Authentication failed."));
    }
  }

  /**
   * Creates the user.
   *
   * @param accessToken the access token
   * @param userId the user id
   * @return true, if successful
   */
  public static boolean createUser(String accessToken, long userId)
  {
    
    log.info("Created user " + userId);
    
    User user = new User(userId);

    String response = JavaCurl
        .getUrl("https://graph.facebook.com/oauth/access_token?client_id="
            + Config.AppId + "&client_secret=" + Config.AppSecret
            + "&grant_type=fb_exchange_token&fb_exchange_token=" + accessToken);
    String[] parts = response.split("[=&]");

    if (parts.length < 4)
    {
      return false;
    }
    String newAccessToken = parts[1];

    GregorianCalendar now = new GregorianCalendar();

    long newTime = Long.valueOf(parts[3].trim()) * 1000 + now.getTimeInMillis();

    GregorianCalendar expireDate = new GregorianCalendar();

    expireDate.setTimeInMillis(newTime);

    response = JavaCurl.getUrl("https://graph.facebook.com/me?access_token="
        + accessToken);

    String email = "";
    GregorianCalendar birthday = null;

    try
    {
      JSONObject jo = new JSONObject(response);
      if (jo.has("gender"))
        user.setGender(jo.getString("gender"));
      if(jo.has("first_name"))
        user.setFirstName(jo.getString("first_name"));
      if(jo.has("last_name"))
        user.setLastName(jo.getString("last_name"));
      if (jo.has("email"))
        email = jo.getString("email");
      if (jo.has("birthday"))
      {
        birthday = getDateFromString(jo.getString("birthday"));
      }
    } catch (JSONException e)
    {
      e.printStackTrace();
    }

    user.setAccessToken(newAccessToken);
    user.setEmail(email);
    if (birthday != null)
    {
      user.setBirthday(birthday.getTimeInMillis());
    }
    user.setExpireTime(expireDate.getTimeInMillis());
    user.save();

    addFriends(newAccessToken, userId);

    return true;
    
  }

  /**
   * Adds the friends.
   * 
   * @param accessToken
   *          the access token
   * @param userId
   *          the user id
   */
  private static void addFriends(String accessToken, long userId)
  {
    String response = JavaCurl
        .getUrl("https://graph.facebook.com/me/friends?fields=first_name,last_name,gender,birthday&access_token="
            + accessToken);
    try
    {
      JSONObject jo = new JSONObject(response);
      if (jo.has("data"))
      {
        JSONArray ja = jo.getJSONArray("data");
        for (int i = 0; i < ja.length(); i++)
        {
          JSONObject friendJo = ja.getJSONObject(i);
          if (friendJo.has("birthday"))
          {
            GregorianCalendar birthday = getDateFromString(friendJo
                .getString("birthday"));
            User friend = new User(friendJo.getLong("id"));
            friend.setBirthday(birthday.getTimeInMillis());
            if(friendJo.has("first_name"))
              friend.setFirstName(friendJo.getString("first_name"));
            if(friendJo.has("last_name"))
              friend.setLastName(friendJo.getString("last_name"));
            if(friendJo.has("gender"))
              friend.setGender(friendJo.getString("gender"));
            friend.save();
            User user = new User(userId);
            user.addFriend(friend);
          }
        }
      }
    } catch (JSONException e)
    {
      e.printStackTrace();
    }
  }

  /**
   * Get Date from string.
   * 
   * @param dateString
   *          the date string
   * @return the date from string
   */
  private static GregorianCalendar getDateFromString(String dateString)
  {
    GregorianCalendar date;
    String[] dateParts = dateString.split("/");
    date = new GregorianCalendar();
    int year = 1900;
    if (dateParts.length >= 3)
    {
      year = Integer.valueOf(dateParts[2].trim());
    }
    date.set(year, Integer.valueOf(dateParts[0].trim()) - 1,
        Integer.valueOf(dateParts[1].trim()));
    return date;
  }

}
